package com.blocks;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.blocks.blocks.Block;
import com.blocks.blocks.ScriptEvaluator;

public class Config { 
	private static Config instance ;
	public static Config getInstance(){  
		if(instance==null){
			instance = new Config();
		}
		return instance;
	}
	private Map<String,String> configmap = new HashMap<String,String>();
	
	
	public Config() {
		configmap.put("distancetoblock", "10");
	}
	// All the variables we want to be user configurable change:
	private float distancetoblock;
	private float playerspeed;
	
	public void loadConfig(String file)
	{
		try
		{
			ScriptEngineManager manager = new ScriptEngineManager();
	        ScriptEngine engine = manager.getEngineByName("JavaScript");
	        
	        engine.put("thisConfig", this);
	        // JavaScript code in a String. This code defines a script object 'obj'
	        // with one method called 'hello'.        
	        System.out.println("File " + file);
	        //InputStream inputStream = ScriptEvaluator.class.getClassLoader().getResourceAsStream(file);
	        InputStream inputStream = new FileInputStream(file);
	        
	        engine.eval(new InputStreamReader(inputStream));

	        // javax.script.Invocable is an optional interface.
	        // Check whether your script engine implements or not!
	        // Note that the JavaScript engine implements Invocable interface.
	        Invocable inv = (Invocable) engine;

	        // get script object on which we want to call the method
	        Object obj = engine.get("config");

	        inv.invokeMethod(obj, "setConfigurable");
	        for(String value: configmap.values()){
	        	System.out.println("CONFIG " + value);
	        }
	        		
		} catch (ScriptException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}catch (NullPointerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	public String getConfigurable(String config)
	{
		return configmap.get(config);
	}
	public String setConfigurable(String config, String value)
	{
		return configmap.put(config, value);
	}
	
	
	
    public void addAllFilesInDirectory(File directory) {
    	try {
 
	        // Get the list of the files contained in the package
	        File[] files = directory.listFiles(getFileFilter());

	        int currrentMasterBlockSize = ScriptBlocksApplication.getInstance().getBlockTypeMap().size();
	        if (files != null) {
	            for (int i = 0; i < files.length; i++) {
	            		load("/blocks/"+files[i].getName() , new Long(i+currrentMasterBlockSize));                  
	            }
	        }
        }catch (NullPointerException e){
        	e.printStackTrace();
        }
    }


    private void load(String scriptFileName, Long masterId) {
    	Block scriptBlock = new Block(scriptFileName, new Long(-1));   	
		scriptBlock.setScriptName(scriptFileName);
		scriptBlock.init();
		ScriptBlocksApplication.getInstance().getBlockTypeMap().put(masterId, scriptBlock);
	}

	private FileFilter getFileFilter() {
        return new FileFilter() {
            public boolean accept(File pathname) {
                return (pathname.getName().endsWith(".js"));
            }
        };
    }
	
	public String toString()
	{
		String values = "";
		for (String value: this.configmap.values())
		{
			values = values + value;
		}
		
		return values;
	}
	

}
